package cc.bukkitPlugin.banitem.command;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import cc.bukkitPlugin.banitem.BanItem;
import cc.bukkitPlugin.banitem.BanItemEnume.ListType;
import cc.bukkitPlugin.banitem.CFG;
import cc.bukkitPlugin.banitem.check.Damage;
import cc.bukkitPlugin.banitem.check.DamageList;
import cc.bukkitPlugin.banitem.check.SimpleWorld;
import cc.bukkitPlugin.banitem.check.WorldTypeItem;
import cc.bukkitPlugin.banitem.check.nbtvalue.ANBTValue;
import cc.bukkitPlugin.banitem.command.analyse.AnalyseResult;
import cc.bukkitPlugin.banitem.command.analyse.ParamDamage;
import cc.bukkitPlugin.banitem.command.analyse.ParamItem;
import cc.bukkitPlugin.banitem.command.analyse.ParamListType;
import cc.bukkitPlugin.banitem.manager.ItemManager;
import cc.bukkitPlugin.util.JsonExtra;
import cc.bukkitPlugin.util.JsonExtra.ClickAction;
import cc.bukkitPlugin.util.JsonExtra.HoverAction;
import cc.bukkitPlugin.util.JsonExtra.Style;

public class CommandShow extends AParamCommand{

    public CommandShow(CommandExc pExector){
        super(pExector,"show");
        this.registerParam(ParamItem.class);
        this.registerParam(ParamDamage.class);
        this.registerParam(ParamListType.class);
    }

    @Override
    public boolean execute(CommandSender pSender,String pLabel,String[] pArgs){
        if(!pSender.hasPermission(this.mPluginName+"."+this.getCommandLabel()))
            return noPermission(pSender);
        AnalyseResult tCmdParam=this.mAnalyseMan.buildParam(pSender,this,pArgs);
        if(tCmdParam.mBuildError)
            return send(pSender,tCmdParam.mBuildErrorMsg);
        if(tCmdParam.mListType==null)
            tCmdParam.mListType=ListType.BAN;
        if(tCmdParam.mItem==null){
            if(!(pSender instanceof Player))
                return send(pSender,"&c参数[i,item]是必须的");
            Player tPlayer=(Player)pSender;
            ItemStack tItem=tPlayer.getItemInHand();
            if(tItem==null||tItem.getType()==Material.AIR)
                return send(pSender,"&c未指定参数[i,item],且手上没有拿着东西");
            tCmdParam.mItem=tItem.getType();
        }

        if(tCmdParam.mWorld.equals(SimpleWorld.defaultWorld)&&pSender instanceof Player)
            tCmdParam.mWorld=SimpleWorld.create(((Player)pSender).getWorld().getName());
        WorldTypeItem tWorldTypeItem=this.mPlugin.getManager(ItemManager.class).getWorldTypeItem(tCmdParam.mWorld,tCmdParam.mListType);

        DamageList tDamageList=tWorldTypeItem.getDamageList(tCmdParam.mItem);
        if(tDamageList==null)
            return send(pSender,"世界:"+tWorldTypeItem.getNamedWorld()+"的"+tCmdParam.mListType.getDisplayName()+"中未发现物品["+tCmdParam.mItem.name()+"("+tCmdParam.mItem.getId()+")"+"]的配置");
        ArrayList<Damage> printDamage=new ArrayList<>();
        if(tCmdParam.mDamage!=null){
            Damage td=tDamageList.get(tCmdParam.mDamage);
            if(td==null)
                return send(pSender,"世界:"+tWorldTypeItem.getNamedWorld()+"的"+tCmdParam.mListType.getDisplayName()+"物品["+tCmdParam.mItem.name()+"]不存在子ID为["+tCmdParam.mDamage+"]的配置");
            printDamage.add(td);
        }else printDamage.addAll(tDamageList.values());

        String prefix=CFG.cfg_color+"  |";
        String jsonPrefix=BanItem.getMsgPrefix()+" "+prefix;
        String opListLabel=tCmdParam.mListType.name().toLowerCase();
        send(pSender,"世界:"+tWorldTypeItem.getNamedWorld()+",当前查询列表: "+tCmdParam.mListType.getDisplayName());
        send(pSender,"damage: "+(tCmdParam.mDamage==null?"未指定":tCmdParam.mDamage));
        send(pSender,prefix+tCmdParam.mItem.name()+"("+tCmdParam.mItem.getId()+")");
        for(Damage sDamage : printDamage){
            String suggest="/banitem remove t:"+opListLabel+" i:"+tCmdParam.mItem.getId()+" d:"+sDamage.mValue;
            if(tCmdParam.mListType==ListType.NBT){
                this.sendJsonInfo(pSender,jsonPrefix+"  ","damage@"+sDamage.mValue+": {}",suggest);
                continue;
            }else this.sendJsonInfo(pSender,jsonPrefix+"  ","damage@"+sDamage.mValue+":",suggest);
            if(tCmdParam.mListType==ListType.NBT)
                continue;
            send(pSender,prefix+"    reason: "+sDamage.getReason());
            Set<String> nbtLabels=sDamage.getNBTLabelSet();
            if(nbtLabels.isEmpty())
                send(pSender,prefix+"    nbt: {}");
            else{
                send(pSender,prefix+"    nbt:");
                for(String snbtLabel : nbtLabels){
                    this.sendJsonInfo(pSender,jsonPrefix+"      ",snbtLabel,suggest+" nl:"+snbtLabel);
                    HashSet<ANBTValue> nbtValues=sDamage.getNBTValues(snbtLabel);
                    for(ANBTValue snbtValue : nbtValues)
                        this.sendJsonInfo(pSender,jsonPrefix+"        ",snbtValue.getRawValue(),suggest+" nl:"+snbtLabel+" nv:"+snbtValue.getRawValue());
                }
            }
        }
        return true;
    }

    private void sendJsonInfo(CommandSender pSender,String pPrefix,String pText,String pSuggest){
        JsonExtra container=new JsonExtra(pPrefix);
        JsonExtra text=new JsonExtra(CFG.link_color+pText);
        text.setStyle(Style.underline);
        text.setHoverEvent(HoverAction.show_text,"点击生成删除命令");
        text.setClickEvent(ClickAction.suggest_command,pSuggest);
        container.addExtra(text).sendToPlayer(pSender);
    }

    @Override
    public ArrayList<String> getHelp(CommandSender pSender,String pLabel){
        ArrayList<String> list=new ArrayList<>();
        if(pSender.hasPermission(this.mPluginName+".show")){
            list.add(CFG.cmd_color+this.mMainCmdLabel+" show [参数:值]...");
            list.add(CFG.help_color+"可选的参数: "+this.getAllowParam());
            list.add(CFG.help_color+"显示一个物品的指定或全部Damage配置");
        }
        return list;
    }

    @Override
    public int getMaxArgumentLength(String pLabel){
        return 3;
    }

}
